Humminbirdhash (#1327)
authortsteven4 <13596209+tsteven4@users.noreply.github.com>
Mon, 19 Aug 2024 23:33:07 +0000 (17:33 -0600)
committerGitHub <noreply@github.com>
Mon, 19 Aug 2024 23:33:07 +0000 (17:33 -0600)
* refactor humminbird handling of wpt numbers.

also:
convert some macros to constexpr.
consistenly use strncpy to move strings to humminbird char arrays.`

* fix clang-diagnostic-missing-field-initializers

defs.h
humminbird.cc
humminbird.h
util.cc

diff --git a/defs.h b/defs.h
index 906bd9a61310e42dfc0344e986869601bc4310d5..d50e49429f06543a0b2197905248598b70ca7162 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -1013,9 +1013,6 @@ enum grid_type {
 #define GRID_INDEX_MIN grid_lat_lon_ddd
 #define GRID_INDEX_MAX grid_swiss
 
-void* gb_int2ptr(int i);
-int gb_ptr2int(const void* p);
-
 QTextCodec* get_codec(const QByteArray& cs_name);
 void list_codecs();
 void list_timezones();
index f829cc796754c93e15fbfcf0e3fd0fd3333bd0d9..e6f7505f53da8ba8e839f310eea13454b8af5a55 100644 (file)
 
 #include "humminbird.h"
 
-#include <QMap>                 // for QMap
+#include <QHash>                // for QHash
 #include <Qt>                   // for CaseInsensitive
 #include <QtGlobal>             // for qRound
 
 #include <cmath>                // for atan, tan, log, sinh
-#include <cstdio>               // for snprintf, SEEK_SET
-#include <cstring>              // for strncpy, memcpy, memset
+#include <cstdio>               // for SEEK_SET
+#include <cstring>              // for strncpy
 #include <numbers>              // for inv_pi, pi
 
 #include "defs.h"               // for Waypoint, be_read32, be_read16, be_write32, fatal, be_write16, route_head, track_add_wpt
@@ -62,10 +62,6 @@ Still, they're useful in the code as a plain signature.
 #define WPT_MAGIC2             0x02030024L // New for 2013.  No visible diff?!
 #define RTE_MAGIC              0x03030088L
 
-#define EAST_SCALE             20038297.0 /* this is i1924_equ_axis*pi */
-#define i1924_equ_axis         6378388.0
-#define i1924_polar_axis       6356911.946
-
 #define BAD_CHARS              "\r\n\t"
 
 /* The hwr data format is records-based, and the records are 36 bytes long. */
@@ -172,8 +168,6 @@ struct HumminbirdBase::group_body_t {
 double
 HumminbirdBase::geodetic_to_geocentric_hwr(const double gd_lat)
 {
-  constexpr double cos_ae = 0.9966349016452;
-  constexpr double cos2_ae = cos_ae * cos_ae;
   const double gdr = gd_lat * std::numbers::pi / 180.0;
 
   return atan(cos2_ae * tan(gdr)) * 180.0 * std::numbers::inv_pi;
@@ -184,8 +178,6 @@ HumminbirdBase::geodetic_to_geocentric_hwr(const double gd_lat)
 double
 HumminbirdBase::geocentric_to_geodetic_hwr(const double gc_lat)
 {
-  constexpr double cos_ae = 0.9966349016452;
-  constexpr double cos2_ae = cos_ae * cos_ae;
   const double gcr = gc_lat * std::numbers::pi / 180.0;
 
   return atan(tan(gcr)/cos2_ae) * 180.0 * std::numbers::inv_pi;
@@ -218,6 +210,8 @@ void
 HumminbirdBase::humminbird_rd_init(const QString& fname)
 {
   fin_ = gbfopen_be(fname, "rb", MYNAME);
+
+  wpt_num_to_wpt_hash.clear();
 }
 
 void
@@ -229,7 +223,7 @@ HumminbirdBase::humminbird_rd_deinit() const
 void
 HumminbirdBase::humminbird_read_wpt(gbfile* fin)
 {
-  humminbird_waypt_t w{0};
+  humminbird_waypt_t w{};
 
   if (! gbfread(&w, 1, sizeof(w), fin)) {
     fatal(MYNAME ": Unexpected end of file!\n");
@@ -275,6 +269,8 @@ HumminbirdBase::humminbird_read_wpt(gbfile* fin)
   case 2: // Waypoint temporary.
   case 3: // Waypoint man-overboard.
     waypt_add(wpt);
+    /* register the point over his internal Humminbird "Number" */
+    wpt_num_to_wpt_hash[w.num] = wpt;
     break;
   case 16: // Waypoint group header.
   case 17: // Waypoint group body.
@@ -283,17 +279,13 @@ HumminbirdBase::humminbird_read_wpt(gbfile* fin)
     delete wpt;
     break;
   }
-
-  /* register the point over his internal Humminbird "Number" */
-  QString buff = QString::number(w.num);
-  map[buff] = wpt;
 }
 
 void
 HumminbirdBase::humminbird_read_route(gbfile* fin) const
 {
 
-  humminbird_rte_t hrte{0};
+  humminbird_rte_t hrte{};
 
   if (! gbfread(&hrte, 1, sizeof(hrte), fin)) {
     fatal(MYNAME ": Unexpected end of file!\n");
@@ -306,13 +298,10 @@ HumminbirdBase::humminbird_read_route(gbfile* fin) const
     route_head* rte = nullptr;
 
     for (int i = 0; i < hrte.count; i++) {
-      char buff[10];
       hrte.points[i] = be_read16(&hrte.points[i]);
 
       /* locate the point over his internal Humminbird "Number" */
-      snprintf(buff, sizeof(buff), "%d", hrte.points[i]);
-      if ((map.value(buff))) {
-        const Waypoint* wpt = map.value(buff);
+      if (const Waypoint* wpt = wpt_num_to_wpt_hash.value(hrte.points[i], nullptr); wpt != nullptr) {
         if (rte == nullptr) {
           rte = new route_head;
           route_add_head(rte);
@@ -328,7 +317,7 @@ void
 HumminbirdBase::humminbird_read_track(gbfile* fin)
 {
 
-  humminbird_trk_header_t th{0};
+  humminbird_trk_header_t th{};
 
   if (! gbfread(&th, 1, sizeof(th), fin)) {
     fatal(MYNAME ": Unexpected end of file reading header!\n");
@@ -436,7 +425,7 @@ void
 HumminbirdBase::humminbird_read_track_old(gbfile* fin)
 {
 
-  humminbird_trk_header_old_t th{0};
+  humminbird_trk_header_old_t th{};
   constexpr int file_len = 8048;
   char namebuf[TRK_NAME_LEN];
 
@@ -601,6 +590,8 @@ HumminbirdBase::humminbird_wr_init(const QString& fname)
 
   waypoint_num = 0;
   rte_num_ = 0;
+
+  wpt_id_to_wpt_num_hash.clear();
 }
 
 void
@@ -618,7 +609,7 @@ HumminbirdBase::humminbird_wr_deinit()
 void
 HumminbirdFormat::humminbird_write_waypoint(const Waypoint* wpt)
 {
-  humminbird_waypt_t hum{0};
+  humminbird_waypt_t hum{};
   int num_icons = std::size(humminbird_icons);
 
   be_write16(&hum.num, waypoint_num++);
@@ -660,8 +651,7 @@ HumminbirdFormat::humminbird_write_waypoint(const Waypoint* wpt)
   QString name = (global_opts.synthesize_shortnames)
                  ? wptname_sh->mkshort_from_wpt(wpt)
                  : wptname_sh->mkshort(wpt->shortname);
-  memset(&hum.name, 0, sizeof(hum.name));
-  memcpy(&hum.name, CSTR(name), name.length());
+  strncpy(hum.name, CSTR(name), sizeof(hum.name)-1);
 
   gbfputuint32(WPT_MAGIC, fout_);
   gbfwrite(&hum, sizeof(hum), 1, fout_);
@@ -837,19 +827,29 @@ HumminbirdFormat::humminbird_rte_tail(const route_head* rte)
   humrte = nullptr;
 }
 
+QString HumminbirdFormat::wpt_to_id(const Waypoint* wpt)
+{
+  QString id = QStringLiteral("%1\01%2\01%3").arg(wpt->shortname)
+                .arg(wpt->latitude, 0, 'f', 9).arg(wpt->longitude, 0, 'f', 9);
+  return id;
+}
+
 void
 HumminbirdFormat::humminbird_write_rtept(const Waypoint* wpt) const
 {
   if (humrte == nullptr) {
     return;
   }
-  int i = gb_ptr2int(wpt->extra_data);
-  if (i <= 0) {
+  QString id = wpt_to_id(wpt);
+
+  if (!wpt_id_to_wpt_num_hash.contains(id)) {
+    // This should not occur, we just scanned all waypoints and routes.
+    warning("Missing waypoint reference in route, point dropped from route.");
     return;
   }
 
   if (humrte->count < MAX_RTE_POINTS) {
-    humrte->points[humrte->count] = i - 1;
+    humrte->points[humrte->count] = wpt_id_to_wpt_num_hash.value(id);
     humrte->count++;
   } else {
     warning(MYNAME ": Sorry, routes are limited to %d points!\n", MAX_RTE_POINTS);
@@ -860,19 +860,10 @@ HumminbirdFormat::humminbird_write_rtept(const Waypoint* wpt) const
 void
 HumminbirdFormat::humminbird_write_waypoint_wrapper(const Waypoint* wpt)
 {
-  Waypoint* tmpwpt;
-
-  QString key = QStringLiteral("%1\01%2\01%3").arg(wpt->shortname)
-                .arg(wpt->latitude, 0, 'f', 9).arg(wpt->longitude, 0, 'f', 9);
-  if (!(tmpwpt = map[key])) {
-    tmpwpt = const_cast<Waypoint*>(wpt);
-    map[key] = const_cast<Waypoint*>(wpt);
-    tmpwpt->extra_data = gb_int2ptr(waypoint_num + 1); /* NOT NULL */
+  QString id = wpt_to_id(wpt);
+  if (!wpt_id_to_wpt_num_hash.contains(id)) {
+    wpt_id_to_wpt_num_hash[id] = waypoint_num;
     humminbird_write_waypoint(wpt);
-  } else {
-    void* p = tmpwpt->extra_data;
-    tmpwpt = const_cast<Waypoint*>(wpt);
-    tmpwpt->extra_data = p;
   }
 }
 
index 17f0c44c81a077a36b8d3236d50df8d0c6e2bd94..ebc34d9da827065749ad8004740f3de65408984c 100644 (file)
@@ -21,7 +21,7 @@
 #ifndef HUMMINBIRD_H_INCLUDED_
 #define HUMMINBIRD_H_INCLUDED_
 
-#include <QMap>      // for QMap
+#include <QHash>     // for QHash
 #include <QString>   // for QString
 #include <QVector>   // for QVector
 
@@ -49,6 +49,15 @@ protected:
 
   /* Constants */
 
+  // constants related to position conversions.
+  static constexpr double i1924_equ_axis = 6378388.0;
+  static constexpr double EAST_SCALE = 20038297.0; /* this is i1924_equ_axis*pi */
+  // static constexpr double i1924_polar_axis = 6356911.946;
+  // We use a modified international 1924 ellipse with a different flattening,
+  // defined by cos_ae = cos(angular eccentricity).
+  static constexpr double cos_ae = 0.9966349016452;
+  static constexpr double cos2_ae = cos_ae * cos_ae;
+
   static constexpr const char* humminbird_icons[] = {
     "Normal",       /*  0 */
     "House",        /*  1 */
@@ -108,7 +117,8 @@ protected:
   MakeShort* trkname_sh{};
   humminbird_rte_t* humrte{};
   int rte_num_{};
-  QMap<QString, Waypoint*> map;
+  QHash<unsigned int, const Waypoint*> wpt_num_to_wpt_hash;
+  QHash<QString, unsigned int> wpt_id_to_wpt_num_hash;
 
   humminbird_trk_header_t* trk_head{};
   humminbird_trk_point_t* trk_points{};
@@ -151,6 +161,7 @@ private:
 
   void humminbird_rte_head(const route_head* rte);
   void humminbird_rte_tail(const route_head* rte);
+  static QString wpt_to_id(const Waypoint*);
   void humminbird_write_rtept(const Waypoint* wpt) const;
   void humminbird_write_waypoint(const Waypoint* wpt);
   void humminbird_write_waypoint_wrapper(const Waypoint* wpt);
diff --git a/util.cc b/util.cc
index 77e724979d0e6706890bcfe0684804327627647e..d0dcbcd13869183362674f390e24a272b94c9d4e 100644 (file)
--- a/util.cc
+++ b/util.cc
@@ -958,33 +958,6 @@ QString get_filename(const QString& fname)
   return QFileInfo(fname).fileName();
 }
 
-/*
- * gb_int2ptr: Needed, when sizeof(*void) != sizeof(int) ! compiler warning !
- */
-void* gb_int2ptr(const int i)
-{
-  union {
-    void* p;
-    int i;
-  } x = { nullptr };
-
-  x.i = i;
-  return x.p;
-}
-
-/*
- * gb_ptr2int: Needed, when sizeof(*void) != sizeof(int) ! compiler warning !
- */
-int gb_ptr2int(const void* p)
-{
-  union {
-    const void* p;
-    int i;
-  } x = { p };
-
-  return x.i;
-}
-
 QTextCodec* get_codec(const QByteArray& cs_name)
 {
   QTextCodec* codec = QTextCodec::codecForName(cs_name);